home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / le.arc / LE.C next >
Encoding:
Text File  |  1985-11-20  |  14.6 KB  |  479 lines

  1. Article 2663 (67 more) in net.sources:
  2. From: peter@baylor.UUCP (Peter da Silva)
  3. Subject: le.c
  4. Message-ID: <401@baylor.UUCP>
  5. Date: 15 Aug 85 17:02:06 GMT
  6. Date-Received: 24 Aug 85 07:33:39 GMT
  7. Distribution: net
  8. Organization: Ancient Illuminated Seers of Bavaria
  9. Lines: 468
  10.  
  11. --MORE--(5%)Having recieved numerous (well, 2) requests for "le", here's the source offered
  12. without comment. 4.2 people will undoubtedly have to patch it to handle the
  13. crufty new directories, but I have done that for a descendent of this (a visual
  14. shell) and it's no hassle. V7 people rejoice: it runs under that venerable
  15. system. I have never tried to convert it ro its descendents fo SIII/SV, so
  16. let me know what luck you have.
  17.  
  18. ---- le.c -----
  19. #include <stdio.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <sys/dir.h>
  23. #include <pwd.h>
  24. #include <grp.h>
  25. #include <time.h>
  26.  
  27. #define D_DEV   01
  28. #define D_INO   02
  29. #define D_MODE  04
  30. #define D_LINKS 010
  31. #define D_UID   020
  32. #define D_GID   040
  33. #define D_RDEV  0100
  34. #define D_SIZE  0200
  35. #define D_ATIME 0400
  36. #define D_MTIME 01000
  37. #define D_CTIME 02000
  38.  
  39. #define D_SMODE 04000
  40. #define D_SUID  010000
  41. #define D_SGID  020000
  42.  
  43. #define FALSE 0
  44. #define TRUE 1
  45.  
  46. #define MAXENTS 512
  47. #define MAXID 64
  48.  
  49. struct entry {
  50.         struct direct e_dir;
  51.         char filler;
  52.         struct stat e_stat;
  53. } entries[MAXENTS];
  54. int nentries;
  55.  
  56. char *errname;
  57. extern int errno;
  58. int xerrno;
  59. char *tab=" ";
  60. long maxsize;
  61. char sizstr[2][10] = {"%6lu%s","%6s%s"};
  62. int dohead=0, dodir=1;
  63. int flags = D_MODE|D_LINKS|D_UID|D_SIZE|D_MTIME;
  64.  
  65. char *emesg[3]={
  66.         "No such error",
  67. #define TOO_MANY 1
  68.         "Too many directory entries",
  69.         0
  70. };
  71.  
  72. getdir(dir)
  73. char *dir;
  74. {
  75.         int     entcmp();
  76.         char *nameof();
  77.         FILE *fp;
  78.         int valid;
  79.  
  80.         if(!(fp = fopen(dir, "r"))) {
  81.                 errname=dir;
  82.                 return FALSE;
  83.         }
  84.  
  85.         maxsize=0L;
  86.         for(nentries=0;
  87.             nentries<MAXENTS &&
  88.               fread(&entries[nentries].e_dir,
  89.                     sizeof entries[nentries].e_dir, 1, fp)>0;
  90.             nentries += valid) {
  91.                 if(valid=entries[nentries].e_dir.d_ino?1:0) {
  92.                         entries[nentries].filler=0;
  93.                         if(stat(nameof(entries[nentries].e_dir.d_name, dir),
  94.                                 &entries[nentries].e_stat
  95.                                )==-1
  96.                           ) {
  97.                                 fclose(fp);
  98.                                 errname=nameof(entries[nentries].e_dir.d_name,
  99.                                                 dir);
  100.                                 return FALSE;
  101.                         }
  102.                         if(entries[nentries].e_stat.st_size>maxsize)
  103.                                 maxsize=entries[nentries].e_stat.st_size;
  104.                 }
  105.         }
  106.  
  107.         if(nentries>=MAXENTS) {
  108.                 errno=0;
  109.                 xerrno=TOO_MANY;
  110.                 errname=dir;
  111.                 return FALSE;
  112.         }
  113.  
  114.         fclose(fp);
  115.  
  116.         qsort(entries, nentries, sizeof(struct entry), entcmp);
  117.  
  118.         setsize(maxsize);
  119.  
  120.         return TRUE;
  121. }
  122.  
  123. setsize(size)
  124. long size;
  125. {
  126.         char tmp[32];
  127.         int siz;
  128.         sprintf(tmp, "%lu", size);
  129.         siz=strlen(tmp);
  130.         if(siz<6) siz=6;
  131.         sprintf(sizstr[0], "%%%dlu%%s", siz);
  132.         sprintf(sizstr[1], "%%%ds%%s", siz);
  133.         if(dohead) {
  134.                 header();
  135.                 dohead=0;
  136.         }
  137. }
  138.  
  139. char *
  140. nameof(name, dir)
  141. char *name, *dir;
  142. {
  143.         char nambuf[BUFSIZ];
  144.  
  145.         if(!dir[0])
  146.                 return name;
  147.         if(dir[0]=='.' && !dir[1])
  148.                 return name;
  149.         else if(dir[0]=='/' && !dir[1]) {
  150.                 sprintf(nambuf, "/%s", name);
  151.                 return nambuf;
  152.         } else {
  153.                 sprintf(nambuf, "%s/%s", dir, name);
  154.                 return nambuf;
  155.         }
  156. }
  157.  
  158. pname(name)
  159. char *name;
  160. {
  161.         int len = 0;
  162.  
  163.         for(;*name; name++)
  164.                 if(*name<' ') { printf("^%c", *name+'@'); len+=2; }
  165.                 else if(*name=='\0177') { printf("^?"); len+=2; }
  166.                 else if(*name>'\0177') { printf("\\%03o", *name); len += 4; }
  167.                 else { putchar(*name); len++; }
  168.         return len;
  169. }
  170.  
  171. entcmp(e1, e2)
  172. struct entry *e1, *e2;
  173. {
  174.         return strcmp(e1->e_dir.d_name, e2->e_dir.d_name);
  175. }
  176.  
  177. fdump(dir)
  178. char *dir;
  179. {
  180.         struct stat sbuf;
  181.  
  182.         if(stat(dir, &sbuf)==-1) {
  183.                 errname=dir;
  184.                 return FALSE;
  185.         } else
  186.                 if(dodir && (sbuf.st_mode&S_IFMT)==S_IFDIR) {
  187.                         if(getdir(dir))
  188.                                 return dump(dir);
  189.                         else
  190.                                 return FALSE;
  191.                 } else {
  192.                         setsize(sbuf.st_size);
  193.                         statout(dir, &sbuf, ".");
  194.                         return TRUE;
  195.                 }
  196. }
  197.  
  198. dump(dir)
  199. char *dir;
  200. {
  201.         int i, j;
  202.         int chars;
  203.  
  204.         if(flags==0) {
  205.                 for(i=0; i<=nentries/5; i++) {
  206.                         chars = 0;
  207.                         for(j=0; j<5; j++) {
  208.                                 if(i+j*nentries/5<nentries)
  209.                                         chars +=
  210.                                         pname(entries[i+j*nentries/5].e_dir.d_name);
  211.                                 if(chars<8) { putchar('\t'); chars=8; }
  212.                                 if(chars<16) { putchar('\t'); chars=16; }
  213.                                 else { putchar(' '); chars++; }
  214.                                 chars %= 16;
  215.                         }
  216.                         putchar('\n');
  217.                 }
  218.         }
  219.         else for(i=0; i<nentries; i++)
  220.                 statout(entries[i].e_dir.d_name,
  221.                         &entries[i].e_stat, dir);
  222.         return TRUE;
  223. }
  224.  
  225. statout(name, sbuf, dir)
  226. char *name;
  227. struct stat *sbuf;
  228. char *dir;
  229. {
  230.         char *u_name(), *g_name();
  231.  
  232.         if(flags&D_DEV)
  233.                 printf("%3d,%3d%s",
  234.                         major(sbuf->st_dev),
  235.                         minor(sbuf->st_dev),
  236.                         tab);
  237.         if(flags&D_RDEV)
  238.                 printf("%3d,%3d%s",
  239.                         major(sbuf->st_rdev),
  240.                         minor(sbuf->st_rdev),
  241.                         tab);
  242.         if(flags&D_INO)
  243.                 printf("%5u%s", sbuf->st_ino, tab);
  244.         if(flags&D_SMODE)
  245.                 printf("%6o%s", sbuf->st_mode, tab);
  246.         if(flags&D_MODE) {
  247.                 int mode = sbuf->st_mode;
  248.                 if((mode&S_IFMT)==S_IFCHR) putchar('c');
  249.                 else if((mode&S_IFMT)==S_IFBLK) putchar('b');
  250.                 else if((mode&S_IFMT)==S_IFDIR) putchar('d');
  251.                 else if((mode&S_IFMT)==S_IFREG) putchar('-');
  252.                 else putchar('?');
  253.                 triad((mode>>6)&7, mode&S_ISUID, 's');
  254.                 triad((mode>>3)&7, mode&S_ISGID, 's');
  255.                 triad(mode&7, mode&S_ISVTX, 't');
  256.                 printf("%s", tab);
  257.         }
  258.         if(flags&D_LINKS)
  259.                 printf("%3u%s", sbuf->st_nlink, tab);
  260.         if(flags&D_SUID)
  261.                 printf("%3d%s", sbuf->st_uid, tab);
  262.         if(flags&D_UID)
  263.                 printf("%-8s%s", u_name(sbuf->st_uid), tab);
  264.         if(flags&D_SGID)
  265.                 printf("%3d%s", sbuf->st_gid, tab);
  266.         if(flags&D_GID)
  267.                 printf("%-8s%s", g_name(sbuf->st_gid), tab);
  268.         if(flags&D_SIZE)
  269.                 printf(sizstr[0], sbuf->st_size, tab);
  270.         if((flags&~(D_ATIME|D_MTIME|D_CTIME)) &&
  271.            (flags&(D_ATIME|D_MTIME|D_CTIME))) putchar(' ');
  272.         if(flags&D_ATIME)
  273.                 printime(&sbuf->st_atime);
  274.         if(flags&D_MTIME)
  275.                 printime(&sbuf->st_mtime);
  276.         if(flags&D_CTIME)
  277.                 printime(&sbuf->st_ctime);
  278.         pname(nameof(name, dir));
  279.         putchar('\n');
  280. }
  281.  
  282. struct idtab {
  283.         int id_id;
  284.         char id_name[10];
  285. } u_list[MAXID], g_list[MAXID];
  286. int u_ptr=0, g_ptr=0;
  287.  
  288. char *
  289. u_name(uid)
  290. int uid;
  291. {
  292.         int i;
  293.         struct passwd *pwptr, *getpwuid();
  294.  
  295.         for(i=0; i<u_ptr; i++)
  296.                 if(u_list[i].id_id==uid)
  297.                         return u_list[i].id_name;
  298.  
  299.         u_list[u_ptr].id_id=uid;
  300.  
  301.         if(pwptr=getpwuid(uid)) {
  302.                 for(i=0; pwptr->pw_name[i]>' '; i++)
  303.                         u_list[u_ptr].id_name[i]=pwptr->pw_name[i];
  304.                 u_list[u_ptr].id_name[i]=0;
  305.         } else
  306.                 sprintf(u_list[u_ptr].id_name, "%d", uid);
  307.  
  308.         return u_list[u_ptr++].id_name;
  309. }
  310.  
  311. char *
  312. g_name(gid)
  313. int gid;
  314. {
  315.         int i;
  316.         struct group *grptr, *getgrgid();
  317.  
  318.         for(i=0; i<g_ptr; i++)
  319.                 if(g_list[i].id_id==gid)
  320.                         return g_list[i].id_name;
  321.  
  322.         g_list[g_ptr].id_id=gid;
  323.  
  324.         if(grptr=getgrgid(gid)) {
  325.                 for(i=0; grptr->gr_name[i]>' '; i++)
  326.                         g_list[g_ptr].id_name[i]=grptr->gr_name[i];
  327.                 g_list[g_ptr].id_name[i]=0;
  328.         } else
  329.                 sprintf(g_list[g_ptr].id_name, "%d", gid);
  330.  
  331.         return g_list[g_ptr++].id_name;
  332. }
  333.  
  334. printime(clock)
  335. long *clock;
  336. {
  337.         struct tm *tmbuf, *localtime();
  338.         static char *months[12]= {
  339.                 "Jan","Feb","Mar","Apr","May","Jun",
  340.                 "Jul","Aug","Sep","Oct","Nov","Dec"
  341.         };
  342.  
  343.         tmbuf=localtime(clock);
  344.         printf("%2d %3s %02d %2d:%02d %s",
  345.                 tmbuf->tm_mday,
  346.                 months[tmbuf->tm_mon],
  347.                 tmbuf->tm_year,
  348.                 tmbuf->tm_hour,
  349.                 tmbuf->tm_min,
  350.                 tab);
  351. }
  352.  
  353. header()
  354. {
  355.         if(flags&D_DEV)
  356.                 printf("%7s%s", "IDev", tab);
  357.         if(flags&D_RDEV)
  358.                 printf("%7s%s", "Rdev", tab);
  359.         if(flags&D_INO)
  360.                 printf("%5s%s", "Inode", tab);
  361.         if(flags&D_SMODE)
  362.                 printf("%6s%s", "Mode", tab);
  363.         if(flags&D_MODE)
  364.                 printf("%-10s%s", "Long mode", tab);
  365.         if(flags&D_LINKS)
  366.                 printf("%3s%s", "Lnx", tab);
  367.         if(flags&D_SUID)
  368.                 printf("%3s%s", "UID", tab);
  369.         if(flags&D_UID)
  370.                 printf("%-8s%s", "User", tab);
  371.         if(flags&D_SGID)
  372.                 printf("%3s%s", "GID", tab);
  373.         if(flags&D_GID)
  374.                 printf("%-8s%s", "Group", tab);
  375.         if(flags&D_SIZE)
  376.                 printf(sizstr[1], "Size", tab);
  377.         if((flags&~(D_ATIME|D_MTIME|D_CTIME)) &&
  378.            (flags&(D_ATIME|D_MTIME|D_CTIME))) putchar(' ');
  379.         if(flags&D_ATIME)
  380.                 printf("%-16s%s", "Access time", tab);
  381.         if(flags&D_MTIME)
  382.                 printf("%-16s%s", "Modify time", tab);
  383.         if(flags&D_CTIME)
  384.                 printf("%-16s%s", "Inode time", tab);
  385.         if(flags)
  386.                 printf("%s\n", "File name");
  387. }
  388.  
  389. triad(bits, special, code)
  390. int bits, special;
  391. char code;
  392. {
  393.         if(bits&4) putchar('r');
  394.         else putchar('-');
  395.  
  396.         if(bits&2) putchar('w');
  397.         else putchar('-');
  398.  
  399.         if(special) putchar(code);
  400.         else if(bits&1) putchar('x');
  401.         else putchar('-');
  402. }
  403.  
  404. main(ac, av)
  405. int ac;
  406. char **av;
  407. {
  408.         int i, j;
  409.         int exit_status = 0;
  410.         int filed=0;
  411.  
  412.         for(i=1; i<ac; i++) {
  413.                 if(av[i][0]=='-')
  414.                         for(j=1; av[i][j]; j++)
  415.                                 switch(av[i][j]) {
  416.                                         case 'T':
  417.                                                 if(av[i][j+1])
  418.                                                         tab = &av[i][++j];
  419.                                                 else
  420.                                                         tab = &av[++i][j=0];
  421.                                                 while(av[i][j]) j++;
  422.                                                 j--;
  423.                                                 break;
  424.                                         case 'N': flags = 0; break;
  425.                                         case 'A': flags = -1; break;
  426.                                         case 'D': dodir=!dodir; break;
  427.                                         case 'd': flags ^= D_DEV; break;
  428.                                         case 'i': flags ^= D_INO; break;
  429.                                         case 'm': flags ^= D_MODE; break;
  430.                                         case 'M': flags ^= D_SMODE; break;
  431.                                         case 'l': flags ^= D_LINKS; break;
  432.                                         case 'u': flags ^= D_UID; break;
  433.                                         case 'U': flags ^= D_SUID; break;
  434.                                         case 'g': flags ^= D_GID; break;
  435.                                         case 'G': flags ^= D_SGID; break;
  436.                                         case 'r': flags ^= D_RDEV; break;
  437.                                         case 's': flags ^= D_SIZE; break;
  438.                                         case 'a': flags ^= D_ATIME; break;
  439.                                         case 't': flags ^= D_MTIME; break;
  440.                                         case 'c': flags ^= D_CTIME; break;
  441.                                         case 'h': dohead=!dohead; break;
  442.                                         case 'H': header(); break;
  443.                                         default:
  444.                                                 printf("Unknown option -%c.\n", av[i][j]);
  445.                                                 printf("\tUsage %s [-A|-N] [-diMmlUuGgrsatc] [-Ttab] [-Hh] [-D] [file]...\n", av[0]);
  446.                                                 break;
  447.                                 }
  448.                 else {
  449.                         filed=1;
  450.                         if(!fdump(av[i])) {
  451.                                 fperror(av[0], errname);
  452.                                 exit_status=errno?errno:(-xerrno);
  453.                         }
  454.                 }
  455.         }
  456.         if(!filed)
  457.                 if(!fdump(".")) {
  458.                         fperror(av[0], errname);
  459.                         exit_status=errno;
  460.                 }
  461.  
  462.         if(dohead) header();
  463.         exit(exit_status);
  464. }
  465.  
  466. fperror(prog, file)
  467. char *prog, *file;
  468. {
  469.         fprintf(stderr, "%s -- ", prog);
  470.         if(errno)
  471.                 perror(file);
  472.         else
  473.                 fprintf(stderr, "%s: %s\n", file, emesg[xerrno]);
  474. }
  475. --
  476.         Peter da Silva (the mad Australian)
  477.                 UUCP: ...!shell!neuro1!{hyd-ptd,baylor,datafac}!peter
  478.                 MCI: PDASILVA; CIS: 70216,1076
  479.